package com.ding.common;

import java.io.IOException;
import java.net.Socket;

//通道是可复用的
public class Channel {

    private Pool pool;

    public void setPool(Pool pool) {
        this.pool = pool;
    }

    public Pool getPool() {
        return pool;
    }

    private Repeater repeater;

    public void setRepeater(Repeater repeater) {
        this.repeater = repeater;
    }

    public Repeater getRepeater() {
        return repeater;
    }

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    private String introducerId;

    public String getIntroducerId() {
        return introducerId;
    }

    public void setIntroducerId(String introducerId) {
        this.introducerId = introducerId;
    }

    private AfterCloseStrategy afterCloseStrategy;

    public void setAfterCloseStrategy(AfterCloseStrategy afterCloseStrategy) {
        this.afterCloseStrategy = afterCloseStrategy;
    }

    public AfterCloseAnotherStrategy getAfterCloseAnotherStrategy() {
        return afterCloseAnotherStrategy;
    }

    private AfterCloseAnotherStrategy afterCloseAnotherStrategy;

    public void setAfterCloseAnotherStrategy(AfterCloseAnotherStrategy afterCloseAnotherStrategy) {
        this.afterCloseAnotherStrategy = afterCloseAnotherStrategy;
    }

    public AfterCloseStrategy getAfterCloseStrategy() {
        return afterCloseStrategy;
    }

    private Socket socket;

    public void setSocket(Socket socket) {
        close();
        this.socket = socket;
        this.closed = false;
    }

    public Channel() {
    }

    public Channel(Socket socket) {
        if (socket.isClosed()) {
            return;
        }
        this.socket = socket;
    }

    public Socket getSocket() {
        return socket;
    }

    private boolean closed = false;

    public void setClosed(boolean closed) {
        this.closed = closed;
    }

    public boolean isClosed() {
        return closed;
    }

    //非主动关闭
    public void close() {
        close(false);
    }

    public void close(boolean active) {

        if (!isClosed()) {
            try {
                if (this.socket != null) {
                    this.socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NullPointerException e) {
                e.printStackTrace();
            }

            if (this.afterCloseStrategy != null) {
                this.afterCloseStrategy.afterClose();
            }
            if (repeater != null) {
                if (repeater.getLeft() == this) {
                    if (!active) {
                        Channel right = repeater.getRight();
                        if (right != null) {
                            if (right.afterCloseAnotherStrategy != null) {
                                right.afterCloseAnotherStrategy.afterClose();
                            }
                        }
                    }
                } else if (repeater.getRight() == this) {
                    if (!active) {
                        Channel left = repeater.getLeft();
                        if (left != null) {
                            if (left.afterCloseAnotherStrategy != null) {
                                left.afterCloseAnotherStrategy.afterClose();
                            }
                        }
                    }
                }
            }
            this.closed = true;
        }
    }

    public void removeSelfFromPool() {
        if (this.pool != null) {
            this.pool.remove(this);
        }
    }

    public void removeSelfFromRepeater() {
        if (this.repeater != null) {
            if (this.repeater.getLeft() == this) {
                this.repeater.setLeft(null);
            } else if (this.repeater.getRight() == this) {
                this.repeater.setRight(null);
            }
        }
    }

}
